﻿
namespace Common.Algorithm.Core.LocalTest;

public class OcTreeExecute
{ 
    public static string filePath { get; set; }
    public static int dataNum { get; set; } = 10;

    public static Point[] Coordinate;

    public static List<GeometryPoint3d> geometryTests { get; set; } = new List<GeometryPoint3d>();

    private static Random random { get; set; } = new Random();
    public OcTreeExecute()
    {
        GetData();
        List<GeometryPoint3d> geometries = geometryTests = BuildGeoms(); //拿到图形对象
         
        geometries.ForEach(g =>
            g.positon = g.positon + new Point3d(0, 0, random.Next(-2000, 2000)));
        //geometryTests = geometries = geometries.GetRange(0, 8).ToList();

        var minPntX = geometries.Min(g => g.positon.X - 100);
        var maxPntX = geometries.Max(g => g.positon.X + 100);
        var minPntY = geometries.Min(g => g.positon.Y - 100);
        var maxPntY = geometries.Max(g => g.positon.Y + 100);
        var minPntZ = geometries.Max(g => g.positon.Z - 100);
        var maxPntZ = geometries.Max(g => g.positon.Z + 100);
        Cube maxRect = new Cube(new Point3d(minPntX, minPntY, minPntZ), new Point3d(maxPntX, maxPntY, maxPntZ));//读取到整个图形的最大区域

        Func<GeometryPoint3d, Cube> func = (geo) => { return geo.GenRect(); };

        //新建四叉树对象
        OcTreeNode<GeometryPoint3d> qtr = new OcTreeNode<GeometryPoint3d>(maxRect, 0);
        OcTreeNode<GeometryPoint3d>.getBBoxFunc = func;
        //将对象插入四叉树完成构建
        foreach (var geo in geometries)
        {
            qtr.Insert(geo);//插入对象
        }
        Console.WriteLine("-------------");
        var nodes = qtr.GetAllNodes();
        Console.WriteLine(nodes.Count());
        Console.WriteLine(nodes.Where(n => n.items.Count != 0).Count());

        cubes = nodes.Select(n => n.envelop).ToList();
    }
    public static List<Cube> cubes { get; set; }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="Path"></param>
    /// <param name="N"></param>
    public static void GetData()
    {
        int i = 0;
        Coordinate = new Point[dataNum];
        using (StreamReader sr = new StreamReader(filePath, System.Text.Encoding.Default))
        {
            string line;
            while ((line = sr.ReadLine()) != null && i <= dataNum - 1)
            {
                string[] point = line.Split(" ");
                Coordinate[i].X = (int)double.Parse(point[0]);
                Coordinate[i].Y = (int)double.Parse(point[1]);
                i++;
            }
        }
    }

    public static List<GeometryPoint3d> BuildGeoms()
    {
        List<GeometryPoint3d> geometries = new List<GeometryPoint3d>();
        for (int i = 0; i < Coordinate.Length; i++)
        {
            var pnt = Coordinate[i];
            var geom = new GeometryPoint3d();
            geom.id = i;
            geom.positon = new Point3d(pnt.X, pnt.Y, 0);
            geom.raidus = 1;
            geometries.Add(geom);
        }
        return geometries;
    }

    public class GeometryPoint3d
    {
        public int id { get; set; }
        public Point3d positon { get; set; }
        public double raidus { get; set; } = 2d;

        public Cube GenRect()
        {
            return new Cube(
                    new Point3d(positon.X - raidus, positon.Y - raidus, positon.Z - raidus),
                    new Point3d(positon.X + raidus, positon.Y + raidus, positon.Z - raidus));
        }
    }
}
